/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.ncsu.csc573.project1.peer;

import edu.ncsu.csc573.project1.util.Constants;
import edu.ncsu.csc573.project1.util.Constants.PPMethod;
import edu.ncsu.csc573.project1.util.Constants.Status;
import edu.ncsu.csc573.project1.util.HeaderField;
import edu.ncsu.csc573.project1.util.PPRequest;
import edu.ncsu.csc573.project1.util.PPResponse;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 *
 * @author svpendse1
 */
public class DownloadClient { 
    Socket downloadSocket;
    String uploadServerHostName;
    int uploadServerPortNumber;
    String downloadClientHostName;
    String osName;
    DataInputStream in;
    DataOutputStream out;

    public DownloadClient(String hostName, int portNumber) {
        this.uploadServerHostName = hostName;
        this.uploadServerPortNumber = portNumber;
        this.osName = System.getProperty("os.name");
        try {
            this.downloadClientHostName = InetAddress.getLocalHost().getHostAddress();
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.startConnection();
    }

    public void startConnection() {
        try {
            downloadSocket = new Socket(uploadServerHostName,
                                        uploadServerPortNumber);
        } catch (Exception e) {
            System.err.println("Failed to create socket");
        }
        
        try {
            in = new DataInputStream(downloadSocket.getInputStream());
            out = new DataOutputStream(downloadSocket.getOutputStream());
        } catch (IOException e) {
            System.err.println("Failed to create reader/writers for the download client");
        }
    }
    public void closeConnection() {
        try {
            PPRequest request = new PPRequest.PPRequestBuilder().exchangeMethod(PPMethod.CLOSE).version(Constants.kVersion).host(new HeaderField("Host", this.downloadClientHostName)).os(new HeaderField("os", this.osName)).build();

            out.writeInt(request.getRequestMessage().length());
            out.writeBytes(request.getRequestMessage());
            in.close();
            out.close();
            downloadSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String downloadRfc(int rfcNumber) {

        PPRequest request = new PPRequest.PPRequestBuilder().exchangeMethod(PPMethod.GET).rfcNumber(rfcNumber).version(Constants.kVersion).host(new HeaderField("Host", downloadClientHostName)).os(new HeaderField("OS", osName)).build();

        try {
            System.out.println(request.getRequestMessage());
            out.writeInt(request.getRequestMessage().length());
            out.writeBytes(request.getRequestMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            byte input[] = new byte[in.readInt()];
            in.readFully(input);
            String message = new String(input);
            PPResponse response = PPResponse.parseFromString(message);
            if (response == null) {
                 JOptionPane.showMessageDialog(new JFrame(), "Unable to parse response from UploadServer@" + uploadServerHostName, "Parse Error", JOptionPane.ERROR_MESSAGE);
            } else if (response.getStatus() == Status.OK) {
                return response.getData(); 
            } else if (response.getStatus() == Status.BAD_REQUEST) {
                 JOptionPane.showMessageDialog(new JFrame(), "Bad Request", "Bad Request", JOptionPane.ERROR_MESSAGE);
            } else if (response.getStatus() == Status.NOT_FOUND) {
                 JOptionPane.showMessageDialog(new JFrame(), "RFC " + rfcNumber + " not found at peer", "RFC Not Found", JOptionPane.ERROR_MESSAGE);
            } else if (response.getStatus() == Status.P2P_CI_VERSION_NOT_SUPPORTED) {
                 JOptionPane.showMessageDialog(new JFrame(), "Version not supported by Peer", "Unsupported Version", JOptionPane.ERROR_MESSAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static void testDownloadClient() {
        DownloadClient client = new DownloadClient("127.0.0.1", 1024);
        System.out.println(client.downloadRfc(1001));
        client.closeConnection();
    }

    public static void main(String[] args) {
        testDownloadClient();
    }
}
